package com.simulation.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.simulation.common.constant.Constants;
import com.simulation.common.utils.SecurityUtils;
import com.simulation.common.utils.StringUtils;
import com.simulation.web.domain.TechCollection;
import com.simulation.web.domain.TechPost;
import com.simulation.web.domain.TechTaskSubmissions;
import com.simulation.web.domain.TechTasks;
import com.simulation.web.dto.TaskSubmissionsDTO;
import com.simulation.web.dto.TechTaskDTO;
import com.simulation.web.dto.TechTeamMembersDTO;
import com.simulation.web.mapper.*;
import com.simulation.web.service.CollectionPostService;
import com.simulation.web.service.TaskService;
import com.simulation.web.utils.PostStatusEnum;
import com.simulation.web.utils.RelatedTypeEnum;
import com.simulation.web.utils.TaskEnum;
import com.simulation.web.vo.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author 唐雄杰
 * @Date 2024-08-25 23:01
 **/
@Service
@AllArgsConstructor
public class TaskServiceImpl implements TaskService {
    private final TaskMapper taskMapper;

    private final TeamMemberMapper teamMemberMapper;

    private final TaskSubmissionsMapper taskSubmissionsMapper;

    private final PostMapper postMapper;

    private final CollectionMapper collectionMapper;

    private final MinioTemplate minioTemplate;

    private final CollectionPostService collectionPostService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int createTask(TechTasks techTasks) {
        techTasks.setPublishTime(LocalDateTime.now());
        techTasks.setCreateUserId(SecurityUtils.getUserId());
        techTasks.setProgress(Constants.DEFAULT_PROCESS);
        techTasks.setStatus(TaskEnum.PROCESSING.name().toLowerCase());
        // 查询当前团队中的人员
        TechTeamMembersDTO techTeamMembersDTO = new TechTeamMembersDTO();
        techTeamMembersDTO.setTeamId(techTasks.getTeamId());
        // 创建任务
        taskMapper.createTask(techTasks);
        List<TechTaskSubmissions> taskSubmissions = new ArrayList<>();
        if (techTasks.getRelatedType().equals(RelatedTypeEnum.POST.name().toLowerCase())) {
            // 查询源项目信息
            TechPostVO techPostVO = postMapper.getById(techTasks.getRelatedId());
            // 查找团队中的成员
            List<TechTeamMembersVO> membersList = teamMemberMapper.getTeamMembersPaged(techTeamMembersDTO);
            if (CollectionUtil.isEmpty(membersList)) {
                return 0;
            }
            // 给团队成员分配任务
            membersList.forEach(member -> {
                TechTaskSubmissions taskSubmission = new TechTaskSubmissions();
                taskSubmission.setTaskId(techTasks.getId());
                taskSubmission.setUserId(member.getUserId());
                taskSubmission.setStatus(TaskEnum.PROCESSING.name().toLowerCase());
                // 复制项目资源
                String code = copyCode(techPostVO.getCode());
                // 复制项目信息
                Long relatedId = copyPost(techPostVO, member.getUserId(), code);
                taskSubmission.setRelatedId(relatedId);
                taskSubmission.setRelatedType(techTasks.getRelatedType());
                taskSubmission.setDeadline(techTasks.getDeadline());
                taskSubmissions.add(taskSubmission);
            });
        } else {
            // 查询源合集信息
            TechCollectionVO techCollectionVO = collectionMapper.getById(techTasks.getRelatedId());

            List<TechPostVO> techPostList = postMapper.getPostByCollectionId(techTasks.getRelatedId());
            if (CollectionUtil.isEmpty(techPostList)) {
                return 0;
            }
            // 查找团队中的成员
            List<TechTeamMembersVO> membersList = teamMemberMapper.getTeamMembersPaged(techTeamMembersDTO);
            if (CollectionUtil.isEmpty(membersList)) {
                return 0;
            }
            membersList.forEach(member -> {
                // 复制合集
                Long relatedId = copyCollection(techCollectionVO, member.getUserId());
                // 把项目复制给团队成员
                List<Long> postIdList = new ArrayList<>();
                techPostList.stream().forEach(techPost -> {
                    // 复制项目资源
                    String code = "";
                    if (!StringUtils.isEmpty(techPost.getCode())) {
                        code = copyCode(techPost.getCode());
                    }
                    // 复制项目
                    techPost.setCollectionId(relatedId);
                    long postId = copyPost(techPost, member.getUserId(), code);
                    postIdList.add(postId);
                });
                collectionPostService.insertOne(relatedId, postIdList);
                // 给团队成员分配任务
                TechTaskSubmissions taskSubmission = new TechTaskSubmissions();
                taskSubmission.setTaskId(techTasks.getId());
                taskSubmission.setUserId(member.getUserId());
                taskSubmission.setStatus(TaskEnum.PROCESSING.name().toLowerCase());
                taskSubmission.setRelatedId(relatedId);
                taskSubmission.setRelatedType(techTasks.getRelatedType());
                taskSubmission.setDeadline(techTasks.getDeadline());
                taskSubmissions.add(taskSubmission);
            });
        }
        // 生成任务提交数据
        return taskSubmissionsMapper.batchInsert(taskSubmissions);
    }

    @Override
    public int updateTaskStatus(Long id, String status) {
        return taskMapper.updateTaskStatus(id, status);
    }

    @Override
    public int updateTaskProgress(Long id, double progress) {
        return taskMapper.updateTaskProgress(id, progress);
    }

    @Override
    public int deleteTask(Long id) {
        // 删除任务对应的资源
        TaskSubmissionsDTO taskSubmissionsDTO = new TaskSubmissionsDTO();
        taskSubmissionsDTO.setTaskId(id);
        List<TechTaskSubmissionsVO> taskSubmissionsVOList = taskSubmissionsMapper.getPageByTaskId(taskSubmissionsDTO);
        if (CollectionUtil.isNotEmpty(taskSubmissionsVOList)) {
            taskSubmissionsVOList.forEach(taskSubmissionsVO -> {
                if (taskSubmissionsVO.getRelatedType().equals(RelatedTypeEnum.POST.name().toLowerCase())) {
                    TechPostVO techPostVO = postMapper.getById(taskSubmissionsVO.getRelatedId());
                    minioTemplate.removeFile(techPostVO.getCode());
                    // 删除项目
                    postMapper.delete(techPostVO.getId());
                } else {
                    TechCollectionVO techCollectionVO = collectionMapper.getById(taskSubmissionsVO.getRelatedId());
                    // 删除合集
                    collectionMapper.delete(techCollectionVO.getId());
                    List<TechPostVO> techPostVOList = postMapper.getPostByCollectionId(techCollectionVO.getId());
                    techPostVOList.stream().forEach(techPostVO -> {
                        minioTemplate.removeFile(techPostVO.getCode());
                        // 删除项目
                        postMapper.delete(techPostVO.getId());
                    });
                }
            });
        }
        // 删除任务对应的提交数据
        taskSubmissionsMapper.deleteByTaskId(id);
        // 删除任务
        return taskMapper.deleteTask(id);
    }

    @Override
    public PageInfo<TechTaskVO> getTasksByCreateUserId(TechTaskDTO techTaskDTO) {
        PageHelper.startPage(techTaskDTO.getPageNum(), techTaskDTO.getPageSize());
        List<TechTaskVO> taskVOList = taskMapper.getTasksByCreateUserId(techTaskDTO.getCreateUserId());
        return new PageInfo<>(taskVOList);
    }

    @Override
    public TechTaskVO getTaskById(Long id, String relatedType) {
        TechTaskVO techTaskVO = taskMapper.getTaskById(id, relatedType);
        return techTaskVO;
    }

    @Override
    public PageInfo<TechTaskVO> getTasksByTeamId(TechTaskDTO techTaskDTO) {
        PageHelper.startPage(techTaskDTO.getPageNum(), techTaskDTO.getPageSize());
        List<TechTaskVO> taskVOList = taskMapper.getTasksByTeamId(techTaskDTO.getTeamId());
        return new PageInfo<>(taskVOList);
    }

    private Long copyPost(TechPostVO oldPost, Long userId, String code) {
        TechPost techPost = new TechPost();
        BeanUtil.copyProperties(oldPost, techPost);
        techPost.setCode(code);
        techPost.setUserId(userId);
        techPost.setStatus(PostStatusEnum.TASK.name().toLowerCase());
        techPost.setViewCount(0);
        techPost.setFavoriteCount(0);
        techPost.setCommentCount(0);
        techPost.setFollowCount(0);
        techPost.setPublishTime(new Date());
        techPost.setId(null);
        postMapper.insert(techPost);
        return techPost.getId();
    }

    private Long copyCollection(TechCollectionVO oldCollection, Long userId) {
        TechCollection techCollection = new TechCollection();
        BeanUtil.copyProperties(oldCollection, techCollection);
        techCollection.setUserId(userId);
        techCollection.setStatus(PostStatusEnum.TASK.name().toLowerCase());
        techCollection.setViewCount(0);
        techCollection.setFavoriteCount(0);
        techCollection.setCommentCount(0);
        techCollection.setFollowCount(0);
        techCollection.setPublishTime(new Date());
        techCollection.setPublishTime(new Date());
        collectionMapper.insertIgnoreNull(techCollection);
        return techCollection.getId();
    }

    private String copyCode(String code) {
        return minioTemplate.copy("template", "projectTemplate", MinioTemplate.getFileExtension(code), code);
    }
}
